package cn.schoolwow.util.module.query.queryPackage.flow;

import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;
import cn.schoolwow.util.module.query.queryPackage.domain.QueryPackageOption;

import java.util.ArrayList;
import java.util.List;

public class ConvertToClassListFlow implements BusinessFlow {

    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        setClassLoaderList(flowContext);
        loadClass(flowContext);
        filterClass(flowContext);
    }

    @Override
    public String name() {
        return "类名转换为类列表";
    }

    private void setClassLoaderList(FlowContext flowContext){
        List<ClassLoader> classLoaderList = new ArrayList<>();

        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
        classLoaderList.add(Thread.currentThread().getContextClassLoader());
        classLoaderList.add(classLoader);
        if(null!=classLoader.getParent()){
            classLoaderList.add(classLoader.getParent());
            if(null!=classLoader.getParent().getParent()){
                classLoaderList.add(classLoader.getParent().getParent());
            }
        }
        flowContext.putTemporaryData("classLoaderList", classLoaderList);
    }

    private void loadClass(FlowContext flowContext){
        List<ClassLoader> classLoaderList = flowContext.checkData("classLoaderList", List.class);
        List<String> classNameList = flowContext.checkData("classNameList", List.class);

        List<Class> classList = new ArrayList<>();
        flowContext.putTemporaryData("classList", classList);
        for(String className:classNameList){
            for(ClassLoader classLoader:classLoaderList){
                try {
                    Class clazz = classLoader.loadClass(className);
                    classList.add(clazz);
                    break;
                }catch (ClassNotFoundException e){
                }
            }
        }
    }

    private void filterClass(FlowContext flowContext){
        QueryPackageOption queryPackageOption = flowContext.checkInstanceData(QueryPackageOption.class);

        if(null==queryPackageOption.clazzRemovePredict){
            return;
        }
        List<Class> classList = flowContext.getData("classList", List.class);
        if(null==classList||classList.isEmpty()){
            return;
        }
        classList.removeIf(queryPackageOption.clazzRemovePredict);
    }
}
